from xml.sax import make_parser
from xml.sax.handler import ContentHandler
from object import AtomicObject, ComplexObject, PointerObject, AllObjects

class ParserHandler(ContentHandler):
	def __init__(self):
		self.allObjects = AllObjects(0, "__all__objects__")
		self.ids = {}
		self.isAtomic, self.isPointer, self.isComplex = False, False, False
		self.isValue, self.isPtr = False, False
		self.atomic, self.pointer, self.complex = None, None, []
		self.complexLevel = -1
		self.value, self.ptr = "", ""
		self.valueType = None
		
	#=================SAX BEGIN========================
	def startElement(self, name, attrs):
		if name == 'complex':
			self.isComplex = True
			self.complexLevel += 1
			self.complex.append(ComplexObject(int(attrs.get("id")),  attrs.get("name")))
			
		elif name == 'atomic':
			self.isAtomic = True
			self.value = ""
			self.atomic = AtomicObject(int(attrs.get("id")),  attrs.get("name"))
			
		elif name == 'pointer':
			self.isPointer = True
			self.ptr = ""
			self.pointer = PointerObject(int(attrs.get("id")),  attrs.get("name"))
			
		elif name == 'value':
			self.isValue = True
			self.valueType = attrs.get("type")
			
		elif name == 'ptr':
			self.isPtr = True
	
	def characters(self,  ch):
		if self.isAtomic:
			if self.isValue:
				self.value += ch
		if self.isPointer:
			if self.isPtr:
				self.ptr += ch
	
	def endElement(self,  name):
		if name == 'complex':
			if self.complexLevel == 0:
				self.allObjects.addChild(self.complex[self.complexLevel])
				self.isComplex = False
			else:
				self.complex[self.complexLevel - 1].addChild(self.complex[self.complexLevel])
			
			self.ids[self.complex[self.complexLevel].oid] = self.complex[self.complexLevel]
			del self.complex[self.complexLevel]
			self.complexLevel -= 1
			
		elif name == 'atomic':
			if self.complexLevel >= 0:
				self.complex[self.complexLevel].addChild(self.atomic)
			else:
				self.allObjects.addChild(self.atomic)
			self.ids[self.atomic.oid] = self.atomic
			self.isAtomic = False
			
		elif name == 'pointer':
			if self.complexLevel >= 0:
				self.complex[self.complexLevel].addChild(self.pointer)
			else:
				self.allObjects.addChild(self.pointer)
			self.ids[self.pointer.oid] = self.pointer
			self.isPointer = False
			
		elif name == 'ptr':
			self.pointer.setPtr(int(self.ptr))
			self.isPtr = False
			self.ptr = ""
			
		elif name == 'value':
			if self.valueType == "int":
				self.atomic.setValue(int(self.value))
			else:
				self.atomic.setValue(self.value)
			self.isValue = False
			self.value = ""
			self.valueType = None
			
#=================SAX END==========================

	def getAllObjects(self):
		return self.allObjects
	
	def getIds(self):
		return self.ids

class XmlParser(object):
	def __init__(self):
		self.parser = make_parser()
	
	def parseXml(self, xml):
		self.parserHandler = ParserHandler()
		self.parser.setContentHandler(self.parserHandler)
		
		self.parser.parse(xml)
		self.parserHandler.getAllObjects()
		return (self.parserHandler.getAllObjects(), self.parserHandler.getIds())
	
	
if __name__ == '__main__':
	xmlParser = XmlParser()
	allObjects, ids = xmlParser.parseXml("xml/m0.xml")
	
	
#	print allObjects, len(allObjects.childrenList)
	print ids, len(ids)